﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace medicine.BaseComponents.Groups
{
    public class Mover
    {
        public event DraggingHandler Dragging;
        public event DropTestHandler DropTest;
        public event AfterDropCompleteHandler AfterDropComplete;

        public Control Parent;
        public Form ParentForm;
        public Control ParentContainer;
        private int isAfterFirstTime;
        public bool isMoving = false;
        public bool isMoved = false;
        public int clickOffsetX = 0;
        public int clickOffsetY = 0;
        public int OriginalX = 0;
        public int OriginalY = 0;
        public DockStyle LastDock;
        public AnchorStyles LastAnchor;

        public Mover(Control Parent)
        {
            this.Parent = Parent;
            this.ParentForm = Parent.FindForm();
            this.ParentContainer = Parent.Parent;
            Parent.MouseDown += new MouseEventHandler(Parent_MouseDown);
            Parent.MouseMove += new MouseEventHandler(Parent_MouseMove);
            Parent.MouseUp += new MouseEventHandler(Parent_MouseUp);
        }
        void Parent_MouseDown(object sender, MouseEventArgs e)
        {
            

            this.startMoving(e.X, e.Y);
        }

        void MakeFormIsTheParent()
        {
            if (this.ParentForm == null)
                this.ParentForm = this.Parent.FindForm();
            if (this.ParentContainer == null)
                this.ParentContainer = this.Parent.Parent;

            this.LastDock = this.Parent.Dock;
            this.LastAnchor = this.Parent.Anchor;

            this.Parent.Dock = DockStyle.None;
            this.Parent.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left))));

            ParentContainer.Controls.Remove(this.Parent);
            ParentForm.Controls.Add(this.Parent);
            this.Parent.BringToFront();

        }

        void Parent_MouseMove(object sender, MouseEventArgs e)
        {

            this.Move(e.X, e.Y);

            if (this.isMoved)
            {
                Rectangle tempRec = new Rectangle(this.Parent.Location, this.Parent.Size);
                if (Dragging != null)
                    Dragging(this.Parent, tempRec);
            }
        }

        void Parent_MouseUp(object sender, MouseEventArgs e)
        {
            if (isMoving)
                this.EndMoving();

            if (this.isMoved)
            {                
                if (this.DropTest != null)
                {
                    Control NewParent = this.DropTest(this.Parent);
                    if (NewParent != null)
                    {
                        ((IDragSource)this.ParentContainer).DragCompleted(this.Parent);
                        this.ParentContainer = NewParent;
                        this.isMoved = false;
                        if (AfterDropComplete != null)
                            this.AfterDropComplete(this, Parent, NewParent);
                        return;
                    }
                }
                this.Parent.Dock = this.LastDock;
                this.Parent.Anchor = this.LastAnchor;
                this.ParentContainer.Controls.Add(((Label)sender));
                this.RestoreOriginalPosition();
                
                this.isMoved = false;

            }
        }
        
        public void startMoving(int clickOffsetX, int clickOffsetY)
        {
            this.isMoving = true;
            this.isMoved = false;
            this.clickOffsetX = clickOffsetX;
            this.clickOffsetY = clickOffsetY;
            this.OriginalX = this.Parent.Left;
            this.OriginalY = this.Parent.Top;
            this.isAfterFirstTime = 0;
        }

        public void Move(int X, int Y)
        {
            if (this.isMoving)
            {
                if (this.isAfterFirstTime == 4)
                {
                    this.isMoved = true;
                    MakeFormIsTheParent();
                }
                if (this.isMoved)
                {
                    this.Parent.Left = X + this.Parent.Left - this.clickOffsetX;
                    this.Parent.Top = Y + this.Parent.Top - this.clickOffsetY;
                }
                this.isAfterFirstTime ++;
            }
        }

        public void EndMoving()
        {
            this.isMoving = false;
        }

        public void RestoreOriginalPosition()
        {
            this.Parent.Left = this.OriginalX;
            this.Parent.Top = this.OriginalY;
        }

    }
}
